/***************************************************************************
 * s -- Copyright Bit Armory Labs 2007
 *
 * FILE:     Program.cs, 20 code lines, [249 Bytes]
 * DATE:     8/25/2007 8:44 PM
 * MODIFIED: 8/25/2007 11:06 PM
 * PATH:     C:\Programming\Projects\Slinks\Slinks
 *
 * NAMESPACE: Slinks
 * CLASS:     Program
 *
 * AUTHOR:   Brian Chavez (Cowboy), bchavez@bitarmory.com
 *
 *                        Licence
 *
 * This library, code generator, and source code
 * is licensed under the terms and conditions defined in the GNU Public
 * License. You are free to use it for non-commercial purposes.
 * If you are going to use any part of it in a commercial 
 * application, contact me and we can work something out.
 * You may use the code generated output of Slink and Slink
 * as a development tool in both commercial and 
 * non-commercial applications.
 *
 * THE SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS", WITHOUT WARRANTY
 * OF ANY KIND, EXPRESS OR IMPLIED. IN NO EVENT SHALL THE AUTHOR BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF THIS
 * SOFTWARE.
 ***************************************************************************/

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using CommandLine.OptParse;
using System.ComponentModel;
using System.IO;
using Slink.Generator;

namespace Slink
{
    class Program
    {
        static void Main( string[] args )
        {
            PropertyFieldParserHelper parserHandler = new PropertyFieldParserHelper( CommandArgs.Instance );
            Parser parser = new Parser( parserHandler );
            parser.OptStyle = OptStyle.Windows;
            parser.UnknownOptHandleType = UnknownOptHandleType.Warning;
            parser.DupOptHandleType = DupOptHandleType.Error;

            parser.OptionWarning += new WarningEventHandler( parser_OptionWarning );
            parser.Parse();

            if( CommandArgs.AreArgumentsValid() == false )
            {
                CommandArgs.PrintUsage();
                return;
            }
            
            Console.WriteLine( "Generating type safety file for " + CommandArgs.Instance.webDirectory );
            
            //at this point, all arguments are valid.  Generate some code now.
            SlinkGenerator.GenerateTypesafeFile(CommandArgs.Instance.webDirectory);


            Console.WriteLine( "Done" );
        }

        static void parser_OptionWarning( Parser sender, OptionWarningEventArgs e )
        {
            Console.WriteLine( "Parser WARNING: " + e.WarningMessage );
        }
    }

    /// <summary>
    /// Command arguments
    /// </summary>
    public sealed class CommandArgs
    {
        #region Command Line Arguments
        /// <summary>
        /// Web directory
        /// </summary>
        [OptDef( OptValType.ValueReq )]
        [LongOptionName( "webproject" )]
        [UseNameAsLongOption( false )]
        [Description( @"This argument should be the full path to your root web directory.  Exmaple: Slink.exe /webproject:C:\Projects\MyAspWebsite" )]
        public string webDirectory;

        #endregion

        /// <summary>
        /// Hide the constructor so nobody can new up CommandArgs
        /// </summary>
        private CommandArgs()
        {
        }


        #region Singleton stuff
        /// <summary>
        /// Instance
        /// </summary>
        private static CommandArgs instance;
        /// <summary>
        /// Instance
        /// </summary>
        /// <returns>Command arguments</returns>
        public static CommandArgs Instance
        {
            get
            {
                return CommandArgs.instance;
            }
        }

        /// <summary>
        /// Create command arguments
        /// </summary>
        static CommandArgs()
        {
            CommandArgs.instance = new CommandArgs();
        }
        #endregion


        #region Validation
        /// <summary>
        /// Are arguments valid
        /// </summary>
        public static bool AreArgumentsValid()
        {
            //Okay, I'm a little verbose here, but at least it's easy to read :)
            if( string.IsNullOrEmpty(CommandArgs.Instance.webDirectory) )
            {
                Console.WriteLine( "Please specify a root web directory." );
                return false;
            }
            if( Directory.Exists(Path.GetFullPath(CommandArgs.Instance.webDirectory)) == false )
            {
                Console.WriteLine( "Invalid web root directory." );
                return false;
            }
            //after all the checks, commandline args are okay.
            return true;
        }
        #endregion

        /// <summary>
        /// Print usage
        /// </summary>
        public static void PrintUsage()
        {
            UsageBuilder ub = new UsageBuilder();
            ub.GroupOptionsByCategory = false;

            ub.BeginSection( "Slink "+Assembly.GetExecutingAssembly().GetName().Version+" for ASP.NET Code Generator\r\nCopyright (C) 2007 Brian Chavez (Bit Armory)" );
            ub.EndSection();

            ub.BeginSection( "Usage:" );
            ub.EndSection();

            ub.BeginSection( "Name" );
            ub.AddParagraph( "Slink.exe" );
            ub.EndSection();

            ub.BeginSection( "Synopsis" );
            ub.AddParagraph( "Slink.exe /webproject:<path>" );
            ub.EndSection();

            ub.BeginSection( "Arguments" );
            PropertyFieldParserHelper pf = new PropertyFieldParserHelper( CommandArgs.Instance );
            ub.AddOptions( pf );

            ub.EndSection();

            ub.ToText( Console.Out, OptStyle.Windows, false );
        }
    }
}

